/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package framework.mining;

import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import weka.clusterers.EM;
import weka.core.Instances;
import weka.clusterers.SimpleKMeans;
import weka.core.converters.ConverterUtils.DataSource;

/**
 *
 * @author Guilherme
 */
public class Statistics
{

    private ArrayList<HashMap<String, Integer>> freqs;
    private final String nameFile = "statistics.arff";

    public static void main(String[] args) throws Exception
    {
        String s = "test teste teste quartenta e teste e quartenta";
        ArrayList<String> list = new ArrayList<>();
        list.add(s);

        Statistics st = new Statistics(list);
        try
        {
            st.computeClusters();
        } catch (IOException ex)
        {
            ex.printStackTrace();
        }

    }

    public Statistics(ArrayList<String> itens)
    {
        if (itens != null)
        {
            this.freqs = new ArrayList<>();
            for (String s : itens)
            {
                freqs.add(this.computeFrequencies(s));
            }
        }
    }

    /**
     * Computa os grupos de um conjunto de itens.
     *
     * @return um HashMap onde a chave é o id do grupo e o valor é um arrayList
     * com os ids dos itens do grupo
     * @throws IOException
     */
    public HashMap<Integer, ArrayList<Integer>> computeClusters() throws IOException, Exception
    {
        this.toFormatDataWeka();

        DataSource source = new DataSource(nameFile);
        Instances data = source.getDataSet();
        // setting class attribute if the data format does not provide this information
        // For example, the XRFF format saves the class attribute information as well
        if (data.classIndex() == -1)
        {
            data.setClassIndex(data.numAttributes() - 1);
        }

        String[] options = new String[2];
        options[0] = "-I";                 // max. iterations
        options[1] = "100";
        EM clusterer = new EM();   // new instance of clusterer
        clusterer.setOptions(options);     // set the options
        clusterer.buildClusterer(data);
        
        
        
        return null;

//        try
//        {
//            // Read the instances from a file.
//
//            FileReader reader = new FileReader(nameFile);
//            Instances instances = new Instances(reader);
//            // We want to ignore the class of the data vectors.
//
//            instances.deleteAttributeAt(2);
//            // Create the clusterer.
//
//            SimpleKMeans thisClusterer = new SimpleKMeans();
//            thisClusterer.setNumClusters(4);
//            thisClusterer.buildClusterer(instances);
//            System.out.println(thisClusterer.getSquaredError());
//            // Try again with a different number of clusters.
//
//            thisClusterer.setNumClusters(5);
//            thisClusterer.buildClusterer(instances);
//            System.out.println(thisClusterer.getSquaredError());
//        } catch (Exception e)
//        {
//            System.out.println(e.getMessage());
//        }
//        return null;
    }

    private HashMap<String, Integer> computeFrequencies(String s)
    {
        HashMap<String, Integer> fs = new HashMap<>();
        int size = s.length();
        Integer f;
        for (int i = 0, j = 0; i < size; i = j + 1)
        {
            for (j = j + 1; (j < size) && (s.charAt(j) != ' '); j++);
            String n = s.substring(i, j).toUpperCase();
            f = fs.get(n);
            if (f != null)
            {
                fs.put(n, f + 1);
            } else
            {
                fs.put(n, 1);
            }

        }
        return fs;
    }

    private void toFormatDataWeka() throws IOException
    {
        BufferedWriter file = new BufferedWriter(new FileWriter(nameFile));

        file.write("@relation statistics\n\n"
                + "@attribute s1 NUMERIC\n"
                + "@attribute s2 NUMERIC\n"
                + "@attribute s3 NUMERIC\n"
                + "@attribute s4 NUMERIC\n"
                + "@attribute s5 NUMERIC\n"
                + "@attribute s6 NUMERIC\n"
                + "@attribute s7 NUMERIC\n"
                + "@attribute s8 NUMERIC\n"
                + "@attribute s9 NUMERIC\n"
                + "@attribute s10 NUMERIC\n\n@data\n");
        int size;
        for (HashMap<String, Integer> m : this.freqs)
        {
            TreeMap<Integer, String> t = new TreeMap<>();
            for (Map.Entry<String, Integer> e : m.entrySet())
            {
                t.put(e.getValue(), e.getKey());
            }
            size = t.size();
            for (int i = 0; i < 10; i++)
            {
                if (i < size)
                {
                    Map.Entry<Integer, String> e = t.lastEntry();

                    if (i == 0)
                    {
                        file.write(this.computeNumber(e.getValue()).toString());
                    } else
                    {
                        file.write(", " + this.computeNumber(e.getValue()).toString());
                    }
                    t.remove(e.getKey());
                } else
                {
                    if (i == 0)
                    {
                        file.write("?");
                    } else
                    {
                        file.write(", ?");
                    }
                }
            }
            file.write("\n");
        }
        file.close();
    }

    private Integer computeNumber(String s)
    {
        int number = 0;
        for (int i = 0; i < s.length(); i++)
        {
            number += s.charAt(i);
        }
        return number;
    }
}
